/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package social.network.merger.api;

import Controllers.FacebookController;
import Controllers.MergedController;
import Controllers.TwitterController;
import Models.MergedFriend;
import java.util.List;
import org.jdom.Document;

/**
 *
 * Clase principal de la API. Debería instanciarse primero, ya que es la que maneja todo el proceso.
 * 
 * @author Daniel Ochoa John
 */
public class SocialNetworkMerger 
{
    
    /*
     * CONSTRUCTOR
     */
    
    
    /**
     * 
     * Constructor de la clase
     * 
     * @param FacebookXML Ruta física del archivo XML que tiene los datos de Facebook
     * @param TwitterXML Ruta física del archivo XML que tiene los datos de Twitter
     * @param K  Denota los K-Contactos mas cercanos que se extraerán en el proceso de unión.
     */
    public SocialNetworkMerger(String FacebookXML,String TwitterXML,int K)
    {
        this.Facebook = FacebookXML;
        this.Twitter = TwitterXML;
        this.K = K;
    }
    
    
    /*
     * GETTERS
     */
    
    /**
     * 
     * Asigna el valor de "K"
     * 
     * @param K Entero que denota los K-Contactos mas cercanos que se extraerán en el proceso de unión.
     */
    public void setK(int K) {
        this.K = K;
    }
    
    public Document ExportToXML()
    {
        return this.MC.ExportarAXML(this.K);
    }
    /*
     * METODOS DE LECTURA
     */
    
    
    /**
     * 
     * Comprueba la validez del archivo XML que contiene los datos de Facebook con el respectivo Schema, posteriormente lee
     * el archivo y guarda los datos. 
     * 
     * 
     * @return Un número entero que da cuenta de distintos estados en la lectura.<br>
     *         Valores de retorno:<br><br>
     * 
     *         1 = OK<br>
     *         2 = Archivo XML no válido<br>
     *         3 = Falló la lectura del archivo<br>
     * 
     */
    public int FacebookRead()
    {
        if(Facebook != null)
        {
            FBC = new FacebookController(Facebook);
            boolean ValidarArchivoXML = FBC.ValidarArchivoXML();
                if(ValidarArchivoXML)
                {
                    boolean LeerArchivo = FBC.LeerArchivo();
                   
                        if(LeerArchivo)
                        {
                            FBC.AnalizaDuplicados();
                            this.FacebookRead = true;
                            return 1;
                        }
                        else
                        {
                            return 3;
                        }
                }
                else
                {
                    return 2;
                }           
        }
        else
        {
            return 4;
        }
        
        
    }
    
     /**
     * 
     * Comprueba la validez del archivo XML que contiene los datos de Twitter con el respectivo Schema, posteriormente lee
     * el archivo y guarda los datos.
     * 
     * 
     * @return Un número entero que da cuenta de distintos estados en la lectura.<br>
     *         Valores de retorno:<br><br>
     * 
     *         1 = OK<br>
     *         2 = Archivo XML no válido<br>
     *         3 = Falló la lectura del archivo<br> 
     * 
     */
    public int TwitterRead()
    {
        if(Twitter != null)
        {
            TC = new TwitterController(Twitter);
            boolean ValidarArchivo = TC.ValidarArchivo();
                if(ValidarArchivo)
                {
                    boolean LeerArchivo = TC.LeerArchivo();
                    
                        if(LeerArchivo)
                        {
                            TC.AnalizaDuplicados();
                            this.TwitterRead = true;
                            return 1;
                        }
                        else
                        {
                            return 3;
                        }
                }
                else
                {
                    return 2;
                }
        }
        else
        {
            return 4;
        }
    }
    
    
    
    /*
     * Metodos Funcionales
     */
    
    
    /**
     * 
     *  Da inicio al proceso de unión de Facebook y Twitter a través de los datos que ya se han leído.
     *  Antes de usar este método es necesario haber leído exitosamente los datos de Twitter y Facebook.
     * 
     * @return True = Tanto Facebook Como Twitter se han leido exitosamente y el proceso de unión se llevó a cabo con éxito.<br>
     *         False = No se han leído Facebook y Twitter.
     */
    public boolean MergeSocialNetworks()
    {
        if((this.FacebookRead)&&(this.TwitterRead))
        {
            MC = new MergedController(TC,FBC);
            MC.AnalizaDuplicados();
            return true;
        }
        else
        {
            return false;
        }
    }
    
    /**
     * 
     * Retorna una lista con los K-Contactos con los que se tiene una mayor relación a través de redes sociales.<br>
     * La lista se retorna en orden descendente, es decir, el contacto con mayor puntaje va primero.
     * 
     * @return Lista enlazada que contiene objetos MergedFriend.
     */
    
    public List<MergedFriend> Lista()
    {
        return this.MC.getListaAmigos(this.K);
    }
    
    /**
     * 
     * Retorna la lista enlazada con los K-Contactos con los que se tiene una mayor relación a través de redes sociales.
     * Según el criterio establecido.<br>
     * La lista se retorna en orden descendente, es decir, el contacto con mayor puntaje va primero.
     * 
     * @param Criterio Es un criterio de relación entre el usuario y el contacto. Los posibles valores son: <br>
     *  Amigo = Describe a Amigos de sexo masculino<br>
     *  Amiga = Describe a Amigos de sexo femenino<br>
     *  Faimlia = Describe a Amigos que son familia del usuario<br>
     *  Novio = Describe al Amigo que es novio del usuario<br>
     *  Novia = Describe a la Amiga que es novia del usuario<br>
     * 
     * @return Lista enlazada que contiene objetos MergedFriend.
     * 
     */
    
    public List<MergedFriend> ListaporRelacion(String Criterio)
    {
        return this.MC.getListaAmigos(Criterio, K);
    }
    
    
     /**
     * 
     * 
     * Retorna la lista enlazada con los K-Contactos con los que se tiene una mayor relación a través de redes sociales.
     * Según el genero establecido.<br>
     * La lista se retorna en orden descendente, es decir, el contacto con mayor puntaje va primero.
     * 
     * @param Preference Es un criterio de genero de los amigos del usuario. Los posibles valores son: <br>
     *  0 = Representa a las mujeres.<br>
     *  1 = Representa a los hombres.<br>
     *
     * 
     * @return Lista enlazada que contiene objetos MergedFriend. 
     */
    public List<MergedFriend> ListaporSexo(int Preference)
    {
        String Sexo = "";
        
        if(Preference == 0)
        {
            Sexo = "female";
        }
        if(Preference == 1)
        {
            Sexo = "male";
        }
        
        return this.MC.getListaAmigosSexo(K, Sexo);
    }

    public int getK() {
        return K;
    }
    
    
    
    
    /**
     * 
     * Retorna la lista enlazada con los K-Contactos con los que se tiene una mayor relación a través de redes sociales.
     * Según los criterios establecidos.<br>
     * La lista se retorna en orden descendente, es decir, el contacto con mayor puntaje va primero.
     * 
     * @param Criterios Una Lista de Strings que contiene los Criterios que serán usados para obtener los K-Contactos.<br>
     * Pueden ser: <br>
     * <table border=1>
     * <tr>
     * <td>Amigo</td>
     * <td>Amiga</td>
     * <td>Familia</td>
     * <td>Novio</td>
     * <td>Novia</td>
     * </tr>
     * </table>
     * @return Lista enlazada que contiene objetos MergedFriend.  
     */
    public List<MergedFriend> ListaporCriterios(List<String> Criterios)
    {
        return this.MC.getListaAmigosCriterios(Criterios, K);
    }
    
    /*
     * Parámetros de entrada
     */
    private String Facebook;
    private String Twitter;
    private int K;
    
    /*
     * Variables controladoras de procesos
     */
    private TwitterController TC;
    private FacebookController FBC;
    private MergedController MC;
    
    
    /*
     * Variables de control de estado
     */
    
    private boolean FacebookRead = false;
    private boolean TwitterRead = false;
    private boolean MergeSocialNetworks = false;
    
}
